#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>

int main()
{
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd < 0) {
        perror("socker err");
        return -1;
    }

    // 绑定
    struct sockaddr_in serv;
    bzero(&serv, sizeof(serv));

    serv.sin_family = AF_INET;
    serv.sin_port = htons(10086);

    // INADDR_ANY  表示使用本地任何可以的 IP
    serv.sin_addr.s_addr = htonl(INADDR_ANY);

    // int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    int ret = bind(lfd, (struct sockaddr*)&serv, sizeof(serv));
    if(ret < 0) {
        perror("bind err");
        return -1;
    }

    // 开始监听
    // int listen(int sockfd, int backlog);
    listen(lfd, 128);

    struct sockaddr_in client;
    socklen_t len = sizeof(client);

    // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    int cfd = accept(lfd, (struct sockaddr*)&client, &len);
    if(cfd < 0) {
        perror("accept err: ");
        return -2;
    }

    // 获取客户端的 IP 和 端口
    char cIP[16];
    memset(cIP, 0, sizeof(cIP));
    // const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
    printf("client: ip = [%s], port: [%d]\n",
           inet_ntop(AF_INET, &client.sin_addr.s_addr, cIP, sizeof(cIP)),
           ntohs(client.sin_port));

    printf("lfd = [%d], cfd = [%d]\n", lfd, cfd);

    // 准备开始通信
    char buf[1024];
    int Len = 0;
    while (1) {
        // 读数据
        memset(buf, 0, sizeof(buf));
        Len = read(cfd, buf, sizeof(buf));
        if(Len <= 0) {
            printf("没有数据，可能是客户端关闭: lem = [%d]\n", Len);
            break;
        }
        printf("len = [%d], buf = [%s]\n", Len, buf);

        // 把客户端的数据，全部转换为 大写，发送出去
        for (int i  = 0; i  < Len; ++i ) {
            buf[i] = toupper(buf[i]);
        }

        // 发送出去
        write(cfd, buf, Len);
    }

    close(cfd);
    close(lfd);

    return 0;
}
